﻿using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using ThoughtWorks.QRCode.Codec;
using PlatformNetCore.Common.Utility;

namespace PlatformNetCore.Common.Helper
{
    /// <summary>
    /// 图片操作类
    /// </summary>
    public class ImageHelper
    {
        /// <summary>
        /// 生成随机的字符串
        /// </summary>
        /// <param name="codeCount">验证码长度</param>
        /// <returns></returns>
        public static string CreateRandomCode(int codeCount)
        {
            string allChar = "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,a,b,c,d,e,f,g,h,i,g,k,l,m,n,o,p,q,r,F,G,H,I,G,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,s,t,u,v,w,x,y,z";
            string[] allCharArray = allChar.Split(',');
            string randomCode = "";
            int temp = -1;
            Random rand = new Random();
            for (int i = 0; i < codeCount; i++)
            {
                if (temp != -1)
                {
                    rand = new Random(i * temp * ((int)DateTime.Now.Ticks));
                }
                int t = rand.Next(35);
                if (temp == t)
                {
                    return CreateRandomCode(codeCount);
                }
                temp = t;
                randomCode += allCharArray[t];
            }
            return randomCode;
        }

        /// <summary>
        /// 创建验证码图片
        /// </summary>
        /// <param name="validateCode">验证码无干扰字符串</param>
        /// <returns></returns>
        public static byte[] CreateValidateGraphic(string validateCode)
        {
            Bitmap image = new Bitmap((int)Math.Ceiling(validateCode.Length * 20.0), 34);
            Graphics g = Graphics.FromImage(image);
            try
            {
                //生成随机生成器
                Random random = new Random();
                //清空图片背景色
                g.Clear(Color.White);
                //画图片的干扰线
                for (int i = 0; i < 25; i++)
                {
                    int x1 = random.Next(image.Width);
                    int x2 = random.Next(image.Width);
                    int y1 = random.Next(image.Height);
                    int y2 = random.Next(image.Height);
                    g.DrawLine(new Pen(Color.Silver), x1, x2, y1, y2);
                }
                Font font = new Font("Arial", 20, (FontStyle.Bold | FontStyle.Italic));
                LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(0, 0, image.Width, image.Height), Color.Blue, Color.DarkRed, 1.2f, true);
                g.DrawString(validateCode, font, brush, 3, 2);


                //画图片的前景干扰线
                for (int i = 0; i < 100; i++)
                {
                    int x = random.Next(image.Width);
                    int y = random.Next(image.Height);
                    image.SetPixel(x, y, Color.FromArgb(random.Next()));
                }
                //画图片的边框线
                g.DrawRectangle(new Pen(Color.Silver), 0, 0, image.Width - 1, image.Height - 1);

                //保存图片数据
                MemoryStream stream = new MemoryStream();
                image.Save(stream, ImageFormat.Jpeg);

                //输出图片流
                return stream.ToArray();
            }
            finally
            {
                g.Dispose();
                image.Dispose();
            }
        }


        /// <summary>
        /// 判断当前图片是否存在，否则生成二维码文件并返回地址
        /// </summary>
        /// <param name="code"></param>
        /// <param name="size"></param>
        /// <returns></returns>
        public static string GetQrCodeImgUrl(IPathProvider pathProvider, string url)
        {
            try
            {
                string fname = IdentityCreator.NextIdentity + ".png";
                string relatePath = string.Format("\\Files\\QrCode\\{0}", DateTime.Now.ToString("yyyyMMdd"));
                string vpath = pathProvider.MapPath(string.Format("\\wwwroot{0}",relatePath));
                string path = vpath + fname;
                
                if (!File.Exists(path))
                {
                    if (!Directory.Exists(vpath))
                    {
                        Directory.CreateDirectory(vpath);
                    }
                    using (MemoryStream ms = new MemoryStream())
                    {
                        QRCodeEncoder endocder = new QRCodeEncoder();
                        //二维码背景颜色
                        endocder.QRCodeBackgroundColor = System.Drawing.Color.White;
                        //二维码编码方式
                        endocder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE;
                        //每个小方格的宽度
                        endocder.QRCodeScale = 10;
                        //二维码版本号
                        endocder.QRCodeVersion = 5;
                        //纠错等级
                        endocder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M;
                        //将json川做成二维码
                        Bitmap bitmap = endocder.Encode(url);
                        bitmap.Save(path);
                    }
                }
                return Path.Combine(relatePath,fname);
            }
            catch (Exception ex)
            {
                LogHelper.Error(ex);
                return string.Empty;
            }
        }

        /// <summary>
        /// 生成缩略图
        /// </summary>
        /// <param name="originalImagePath">源图路径（物理路径）</param>
        /// <param name="thumbnailPath">缩略图路径（物理路径）</param>
        /// <param name="width">缩略图宽度</param>
        /// <param name="height">缩略图高度</param>
        /// <param name="mode">生成缩略图的方式</param> 
        /// <param name="mode1">HW/指定高宽缩放(可能变形)</param> 
        /// <param name="mode2">W/指定宽，高按比例</param> 
        /// <param name="mode3">H/指定高，宽按比例</param> 
        /// <param name="mode4">Cut/指定高宽裁减(不变形)</param> 
        /// <param name="mode5">DB/等比缩放(不变形，如果高大按高，宽大按宽缩放)</param> 
        public static void MakeThumbnail(string originalImagePath, string thumbnailPath, int width, int height, string mode, string type)
        {
            Image originalImage = Image.FromFile(originalImagePath);

            int towidth = width;
            int toheight = height;

            int x = 0;
            int y = 0;
            int ow = originalImage.Width;
            int oh = originalImage.Height;

            switch (mode)
            {
                case "HW":    //指定高宽缩放（可能变形） 
                    break;
                case "W":     //指定宽，高按比例 
                    toheight = originalImage.Height * width / originalImage.Width;
                    break;
                case "H":     //指定高，宽按比例
                    towidth = originalImage.Width * height / originalImage.Height;
                    break;
                case "Cut":   //指定高宽裁减（不变形） 
                    if ((double)originalImage.Width / (double)originalImage.Height > (double)towidth / (double)toheight)
                    {
                        oh = originalImage.Height;
                        ow = originalImage.Height * towidth / toheight;
                        y = 0;
                        x = (originalImage.Width - ow) / 2;
                    }
                    else
                    {
                        ow = originalImage.Width;
                        oh = originalImage.Width * height / towidth;
                        x = 0;
                        y = (originalImage.Height - oh) / 2;
                    }
                    break;
                case "DB":      //等比缩放（不变形，如果高大按高，宽大按宽缩放） 
                    if ((double)originalImage.Width / (double)towidth < (double)originalImage.Height / (double)toheight)
                    {
                        toheight = height;
                        towidth = originalImage.Width * height / originalImage.Height;
                    }
                    else
                    {
                        towidth = width;
                        toheight = originalImage.Height * width / originalImage.Width;
                    }
                    break;
                default:
                    break;
            }

            //新建一个bmp图片
            System.Drawing.Image bitmap = new System.Drawing.Bitmap(towidth, toheight);
            //新建一个画板
            System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap);

            g.CompositingMode = CompositingMode.SourceCopy;
            g.CompositingQuality = CompositingQuality.HighQuality;
            //设置高质量插值法
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            //设置高质量,低速度呈现平滑程度
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.PixelOffsetMode = PixelOffsetMode.HighQuality;

            //清空画布并以透明背景色填充
            g.Clear(System.Drawing.Color.Transparent);

            //在指定位置并且按指定大小绘制原图片的指定部分
            g.DrawImage(originalImage, new System.Drawing.Rectangle(0, 0, towidth, toheight),
            new System.Drawing.Rectangle(x, y, ow, oh),
            System.Drawing.GraphicsUnit.Pixel);

            try
            {
                //保存缩略图
                switch (type.ToLower())
                {
                    case ".jpg":
                        bitmap.Save(thumbnailPath, ImageFormat.Jpeg);
                        break;
                    case ".bmp":
                        bitmap.Save(thumbnailPath, ImageFormat.Bmp);
                        break;
                    case ".gif":
                        bitmap.Save(thumbnailPath, ImageFormat.Gif);
                        break;
                    case ".png":
                        bitmap.Save(thumbnailPath, ImageFormat.Png);
                        break;
                    default:
                        bitmap.Save(thumbnailPath, ImageFormat.Png);
                        break;
                }
            }
            catch (Exception e)
            {
                LogHelper.Error(e);
            }
            finally
            {
                originalImage.Dispose();
                bitmap.Dispose();
                g.Dispose();
            }
        }

    }
}
